<template>
  <div class="bg-f5 report-fixed">
    <div class="report pr">
      <header>
        <div class="report-header-center flex-center-wrap flex-justify-between">
          <div class="flex-center-wrap">
            <img
              class="logo"
              src="//image.zlketang.com/public/news/images/new_official/other/black_logo.png"
              alt=""
            />
            <div class="dor"></div>
            <svg
              class="icon"
              aria-hidden="true"
              style="width: 96px; height: 34px"
            >
              <use
                :xlink:href="
                  +examInitModel === 1
                    ? '#icon-lianxibaogao'
                    : '#icon-kaoshibaogao'
                "
              ></use>
            </svg>
          </div>
          <div class="flex-center cu" @click="goBack">
            <svg
              class="icon"
              aria-hidden="true"
              style="width: 17px; height: 35px;color:#484848"
            >
              <use xlink:href="#icon-fanhui"></use>
            </svg>
            <span class="goback">
              返回答题页
            </span>
          </div>
        </div>
      </header>
      <div class="report-content">
        <div class="report-container">
          <!-- 私教班学习中心试试题基础信息部分 -->
          <private-report
            v-if="+examType === 8"
            :reportList="reportList"
            :examQuestion="examQuestion"
          ></private-report>
          <!-- 非私教班试题基础信息部分 -->
          <div v-else class="report-base">
            <div class="report-title">
              {{ examQuestion.exam_name ? examQuestion.exam_name : '未知考试' }}
            </div>

            <div class="flex-wrap flex-justify-between m-t-30">
              <div class="report-left-info">
                <div
                  class="flex-center-wrap flex-justify-between"
                  v-if="+examInitModel === 2"
                >
                  <div class="flex-center-wrap">
                    <span class="fen-label">
                      得分：
                    </span>
                    <span class="fen-num">
                      {{ scoreResult | tofixedOne }}分
                    </span>
                  </div>
                  <div class="flex-center-wrap">
                    <span class="fen-label">
                      用时：
                    </span>
                    <span class="fen-num juan-time">
                      {{ timeConsumingText }}
                    </span>
                  </div>
                </div>

                <div :class="[+examInitModel === 1 ? '' : 'm-t-20']">
                  <div class="chart-box">
                    <div
                      class="p-time"
                      v-if="+examInitModel === 1 && !isChangeExamModel"
                    >
                      用时：
                      <span class="c-primary">{{ timeConsumingText }}</span>
                    </div>
                    <zl-progress
                      :class="[+examInitModel === 1 ? 'p-t-number' : '']"
                      :progress="allProgress"
                    ></zl-progress>
                  </div>
                  <div
                    :class="[
                      'report-tip',
                      +examInitModel === 1 ? 'p-t-number' : ''
                    ]"
                  >
                    正确率=做对题量（
                    <span class="c-38">{{ allRightNumber }}</span>
                    ）/已做题量（
                    <span class="c-38">{{ allNumber }}</span>
                    ）
                  </div>
                </div>
              </div>

              <div class="report-right-table">
                <el-table
                  :span-method="spanMethod"
                  class="tk-table"
                  max-height="233px"
                  :data="processedTableData"
                  :border="false"
                  style="width: 710px"
                >
                  <el-table-column
                    align="center"
                    header-align="center"
                    prop="title"
                    label="题型"
                    width="156"
                  >
                    <template slot-scope="scope">
                      <div class="ell">
                        {{ scope.row.title }}
                      </div>
                    </template>
                  </el-table-column>
                  <el-table-column
                    align="center"
                    header-align="center"
                    label="做对/已做"
                  >
                    <template slot-scope="scope">
                      <span v-if="typeof scope.row.children_r === 'number'">
                        {{ scope.row.children_r }}/{{ scope.row.totalCount }}
                      </span>
                      <span v-else>{{ scope.row.children_r }}</span>
                    </template>
                  </el-table-column>
                  <el-table-column
                    align="center"
                    header-align="center"
                    prop="accuracy"
                    label="正确率"
                  ></el-table-column>
                  <el-table-column
                    v-if="+examInitModel === 2"
                    align="center"
                    header-align="center"
                    label="得分/总分"
                  >
                    <template slot-scope="scope">
                      {{ scope.row.score | tofixedOne }} /
                      {{ scope.row.partScore }}
                    </template>
                  </el-table-column>
                  <el-table-column
                    align="center"
                    header-align="center"
                    prop="totalCount"
                    label="总题数"
                  >
                    <template slot-scope="scope">
                      {{ scope.row.children.length }}
                    </template>
                  </el-table-column>
                </el-table>
              </div>
            </div>
          </div>

          <div
            :class="['report-lists', +examInitModel === 1 ? 'p-r-8' : '']"
            v-for="(item, index) in getList"
            :key="index"
          >
            <div class="report-item-container">
              <div class="flex-center-wrap flex-justify-between">
                <div class="report-item-title">
                  {{ delTitleIndex(item.title) }}
                </div>

                <div class="flex-center-wrap report-numbs-right">
                  <div class="flex-center-wrap report-numbs-right-item">
                    <span>
                      未做：
                    </span>
                    <span>
                      {{ reportList[index].children_n }}
                    </span>
                  </div>

                  <div
                    class="flex-center-wrap report-numbs-right-item c-success"
                  >
                    <span>
                      答对：
                    </span>
                    <span>
                      {{ reportList[index].children_r }}
                    </span>
                  </div>

                  <div
                    class="flex-center-wrap report-numbs-right-item c-danger"
                  >
                    <span>
                      答错：
                    </span>
                    <span>
                      {{ reportList[index].children_w }}
                    </span>
                  </div>

                  <!-- 考试模式需要显示每部分分数 -->
                  <div
                    class="report-numbs-right-item-total"
                    v-if="+examInitModel === 2"
                  >
                    <span class="f-16 c-danger">
                      {{ reportList[index].score | tofixedOne }}分
                    </span>
                    <span>/{{ reportList[index].partScore }}分</span>
                  </div>
                </div>
              </div>

              <div class="report-tips" v-if="item.description">
                {{ item.description }}
              </div>
              <div
                class="flex-wrap report-list-item-list"
                v-if="isIncludes(['normal', 'dryRun'], paperMajor)"
              >
                <div v-for="(itey, indey) in item.questions" :key="indey">
                  <!-- {{ +itey.type }} -->
                  <div class="w-1140" v-if="+itey.type === 3">
                    <!-- 组合题 -->
                    <div
                      class="zuhe-title"
                      v-if="
                        isArray(item.questions) && item.questions.length > 1
                      "
                    >
                      第{{ indey + 1 }}小题
                    </div>

                    <div class="flex-center-wrap flex-multi-row">
                      <div
                        v-for="(itez, indez) in itey.options"
                        :key="itez.indexId"
                        :class="[
                          'flex-center report-list-item-list-item',
                          getStatusClass(itey.question_id, indez)
                        ]"
                        @click="loadQue(itey)"
                      >
                        {{ indez + 1 }}
                      </div>
                    </div>
                  </div>

                  <div
                    @click="loadQue(itey)"
                    v-else
                    :class="[
                      'flex-center report-list-item-list-item',
                      getStatusClass(itey.question_id)
                    ]"
                  >
                    {{ indey + 1 }}
                  </div>
                </div>
              </div>

              <div
                class="flex-wrap report-list-item-list"
                v-if="paperMajor === 'cpa'"
              >
                <div
                  @click="loadQue(itey)"
                  :class="[
                    'flex-center report-list-item-list-item',
                    getStatusClassCpa(itey)
                  ]"
                  v-for="(itey, indey) in item.children"
                  :key="indey"
                >
                  {{ indey + 1 }}
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
      <div class="report-fixed-bottom flex-center">
        <div
          class="report-fixed-center-content flex-center-wrap flex-justify-end"
        >
          <div
            v-if="isShow"
            class="flex-center report-btn-default cu"
            @click="goToNext"
          >
            {{ +nextPaperType === 1 ? '下一节' : '下一套' }}
          </div>

          <div
            class="flex-center report-btn-default cu m-l-20"
            @click="redo"
            v-if="isShowRedo"
          >
            {{ +examInitModel === 1 ? '再做一次' : '再考一次' }}
          </div>
          <div class="flex-center report-btn-warning cu" @click="goToExamErr">
            错误解析
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import zlProgress from '@/components/exam/zl_progress.vue'
import privateReport from '@/pages/study_center/private_study_center/components/privateReport.vue'
import { saveExamProgress, submitQuestionRecord, resetExam } from '@/api/exam'
export default {
  name: 'examReport',
  components: {
    'zl-progress': zlProgress,
    'private-report': privateReport
  },
  props: {
    nextExamInfo: {
      type: Object,
      default: () => {}
    },
    max_duration: {
      type: Number,
      default: 0
    },
    // 1练习 2考试
    paperType: {
      type: String,
      default: '1'
    },
    nextExamLock: {
      type: Boolean,
      default: false
    },
    paperMajor: {
      // dryRun 万人模考 cpa cpa考试 normal 练习
      type: String,
      default: 'normal'
    },

    // 外部传入的试题数据
    examQuestionInfo: {
      type: Object,
      default: () => {}
    },

    isLoading: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      // 每部分的做题分数统计，按partIndex分
      partAnswerScore: {},
      // 报告列表
      reportList: [],
      examQuestion: {},
      examType: 1,
      // 埋点数据
      zlaBtn: {
        key_name: '',
        key_content: ''
      }
    }
  },
  computed: {
    // 是否显示再做一次
    isShowRedo() {
      let { paperMajor, query } = this

      if (
        (paperMajor === 'dryRun' && +query.is_redo === 2) ||
        paperMajor !== 'dryRun'
      ) {
        return true
      }
      return false
    },
    // 渲染卡片列表
    getList() {
      return this.paperMajor === 'cpa' ? this.reportList : this.parts
    },
    // 扇形进度
    allProgress() {
      return !this.allNumber
        ? 0
        : Math.floor((this.allRightNumber / this.allNumber) * 100)
    },
    // 获取url参数
    query() {
      return this.getQuery(location.search)
    },
    // 已做题数
    allNumber() {
      let result = 0
      this.reportList.forEach(item => {
        result += item.children_r + item.children_w
      })

      return result
    },

    // 做对题数
    allRightNumber() {
      let result = 0
      this.reportList.forEach(item => {
        result += item.children_r
      })

      return result
    },

    // 总分
    scoreResult() {
      let result = 0
      this.reportList.forEach(item => {
        let { score } = item
        if (score) {
          result += score
        }
      })

      return result < 0 ? 0 : result
    },
    // 是否存在下一节
    isAllOver() {
      const { nextExamInfo } = this
      if (this.getType(nextExamInfo) === 'object' && nextExamInfo.isAllOver) {
        return true
      }
      return false
    },

    // 下一节的type
    nextPaperType() {
      let { nextExamInfo } = this
      if (this.getType(nextExamInfo) === 'object' && nextExamInfo.paper_type) {
        return nextExamInfo.paper_type
      }
      return ''
    },
    parts() {
      let { parts } = this.examQuestion
      return parts
    },
    // 已提交过试卷
    isSubmitedPaper() {
      if (this.paperMajor === 'dryRun') {
        return true
      }
      return this.$store.state.exam.isSubmitedPaper
    },
    // 模式 1练习模式 2考试模式（有评分）
    examInitModel() {
      if (this.isSubmitedPaper) {
        return 2
      }
      return this.$store.state.exam.examInitModel
    },

    // 是否存在下一节下一套
    isShow() {
      let { isAllOver } = this
      const { nextExamInfo } = this

      if (this.getType(nextExamInfo) !== 'object') {
        return false
      }
      let { groupName, examName } = nextExamInfo

      if (!groupName && !examName) {
        return false
      }

      if (!isAllOver) {
        return true
      }

      return false
    },

    // 表格合并处理
    processedTableData() {
      return this.reportList.map(row => {
        let { type } = row
        if (+type === 4 || (['cpa'].includes(this.paperMajor) && +type === 3)) {
          return {
            ...row,
            children_r: '暂不支持判断正误'
          }
        }
        return row
      })
    },
    // 用时
    timeConsumingText() {
      return this.$store.getters['exam/timeConsumingText'] || '00:00:00'
    },

    // 是否从考试切换过模式
    isChangeExamModel() {
      return this.$store.getters['exam/isChangeExamModel'] || false
    },
    // 用时
    timeConsuming() {
      if (this.paperMajor === 'dryRun') {
        return (
          (this.examQuestion.nextExamInfo &&
            this.examQuestion.nextExamInfo.timeConsuming) ||
          0
        )
      }
      return this.$store.state.exam.timeConsuming || 0
    }
  },
  watch: {
    examQuestionInfo: {
      handler() {
        this.init()
      },
      deep: true
    },
    zlaBtn: {
      handler() {
        this.sendZlaClick()
      },
      deep: true
    },
    isLoading() {
      this.init()
    }
  },
  filters: {
    // 保留一位小数
    tofixedOne(val) {
      if (!val) {
        return 0
      }
      return Number(val.toFixed(1))
    },
    filterTitle(val) {
      // 最多展示7个字，超过就用...展示
      if (val.length > 7) {
        return val.slice(0, 7) + '...'
      }
      return val
    }
  },
  mounted() {
    this.storage.init()
    this.init()
  },
  methods: {
    init() {
      let { paperMajor, isLoading } = this
      if (isLoading) return
      if (paperMajor === 'dryRun') {
        // 万人模考使用父组件传入的数据
        this.examQuestion = this.deepCopy(this.examQuestionInfo)
        // 获取缓存中的考试时间
        let reportList = storage.get('reportList')
        if (reportList) {
          try {
            reportList = JSON.parse(reportList)
            let reportInfo = reportList.find(
              item => item.exam_id === this.query.exam_id
            )
            if (reportInfo) {
              this.examQuestion.nextExamInfo.timeConsuming =
                reportInfo.timeConsuming || 0
            }
          } catch (e) {}
        }
      } else {
        // 获取缓存的试题数据
        let examQuestion = storage.get(`question_${this.query.exam_id}`)

        if (examQuestion) {
          try {
            this.examQuestion = JSON.parse(examQuestion)
          } catch (e) {
            this.examQuestion = {}
          }
        }
        this.examType = this.examQuestion.exam_type
        this.saveReportInfo()
      }

      // 创建收集统计数据的对象
      this.createPartScore()
      // 判断status及分数
      this.computedScore()
      // 计算出最终渲染数据
      this.computedReportList()
    },
    loadQue(row) {
      let { question_id } = row
      if (question_id) {
        this.zlaBtn = {
          key_name: '考后看答案',
          key_content: question_id
        }
      }

      this.goBack(2)
      this.$emit('choose', row)
    },
    // 修复答案
    fixedAnswer(row) {
      let type = this.getType(row)
      if (type === 'array') {
        return this.deepCopy(row.filter(item => item))
      }

      if (type === 'string') {
        return row.split(',').filter(item => item)
      }
      return []
    },
    isExist(row) {
      return ['0', 0].includes(row) || row
    },
    // 合并表格
    spanMethod({ row, column, rowIndex, columnIndex }) {
      let { type } = row
      const isCpa = +type === 4 || (this.paperMajor === 'cpa' && +type === 3)
      if (isCpa && columnIndex === 1) {
        return {
          rowspan: 1,
          colspan: +this.examInitModel === 1 ? 3 : 4
        }
      } else if (isCpa && columnIndex > 1) {
        return [0, 0]
      }
    },
    // 保存一份报告数据到缓存，目前只保存时间
    saveReportInfo() {
      let { examInitModel } = this
      let { exam_id } = this.query
      if (!exam_id || +examInitModel === 1) return
      let reportList = storage.get('reportList') || '[]'
      const currntReportInfo = {
        exam_id,
        timeConsuming: this.nextExamInfo?.timeConsuming || 0
      }
      try {
        reportList = JSON.parse(reportList)
        let reportInfo = reportList.find(item => item.exam_id === exam_id)
        if (reportInfo) {
          this.nextExamInfo.timeConsuming = reportInfo.timeConsuming || 0
        } else {
          reportList = [...reportList, currntReportInfo]
        }
      } catch (e) {}
      // 保存一份报告数据
      reportList = reportList.map(item => {
        if (item.exam_id === exam_id) {
          item.timeConsuming = this.nextExamInfo?.timeConsuming || 0
        }
        return item
      })
      storage.set('reportList', JSON.stringify(reportList))
    },
    // 去除头部的序号
    delTitleIndex(title) {
      let arr = [
        '一、',
        '二、',
        '三、',
        '四、',
        '五、',
        '六、',
        '七、',
        '八、',
        '九、',
        '十、'
      ]
      // 以这些开头的，去掉
      let reg = new RegExp(`^(${arr.join('|')})`)
      return title.replace(reg, '')
    },
    // 处理时间格式
    getTimeConsuming() {
      let { timeConsuming } = this
      // 处理成yy:MM:ss
      let result = ''
      let time = ''
      time = timeConsuming
      if (time) {
        let hour = Math.floor(time / 3600)
        let minute = Math.floor((time - hour * 3600) / 60)
        let second = time - hour * 3600 - minute * 60
        result = `${hour < 10 ? '0' + hour : hour}:${
          minute < 10 ? '0' + minute : minute
        }:${second < 10 ? '0' + second : second}`
      }

      return result
    },
    async goBack(type = 1) {
      if (type !== 2) {
        this.zlaBtn = {
          key_name: '返回答题页',
          key_content: '返回答题页'
        }
      }
      await this.$nextTick()
      this.$emit('close')
    },
    // 前往错题解析
    goToExamErr() {
      let { exam_id, subject_id } = this.query
      if (!exam_id) {
        this.$message.error('缺少参数exam_id')
        return
      }
      this.zlaBtn = {
        key_name: '错题解析',
        key_content: '错题解析'
      }
      // 将错题数据存入 sessionStorage
      let examQuestionCopy = this.deepCopy(this.examQuestion)
      let { parts, questionsList } = examQuestionCopy
      if (this.isArray(parts)) {
        // 选出错题
        let questionsListCopy = questionsList.filter(item => {
          let { type, options, answer, userAnswer } = item
          let answerFilter = []
          let userAnswerFilter = []
          if (+type === 3) {
            //  对于组合题需要特殊处理 --- 只携带错题过去
            if (this.isArray(options)) {
              let optionsCopy = options.filter((itey, indey) => {
                if ([1, 2].includes(+itey.type) && itey.status === 'w') {
                  answerFilter.push(answer[indey])
                  userAnswerFilter.push(userAnswer[indey])
                  return itey
                }
              })
              item.options = optionsCopy
              if (optionsCopy.length === 0) {
                return false
              }
            }
            item.answer = answerFilter
            item.userAnswer = userAnswerFilter
            return item
          } else {
            if (['w', 'h'].includes(item.status)) {
              return item
            }
          }
        })
        if (questionsListCopy.length === 0) {
          this.$message.warning('您暂无错题哦，继续保持！')
          return
        }
        let list = parts.filter(item => {
          let { questions } = item
          if (this.isArray(questions)) {
            item.questions = questions.filter(itey => {
              return questionsListCopy.some(
                itez => itez.question_id === itey.question_id
              )
            })
          }

          if (this.isArray(item.questions) && item.questions.length > 0) {
            return item
          }
        })

        let arr_ids = questionsListCopy.map(item => item.question_id)

        list = list.map(item => {
          let { answerList } = item
          if (this.isArray(answerList)) {
            item.answerList = answerList.filter(itey => {
              let { question_id } = itey
              if (arr_ids.includes(question_id)) {
                return itey
              }
            })
          }
          return item
        })

        let examErr = sessionStorage.getItem('examErr')
        if (examErr) {
          try {
            examErr = JSON.parse(examErr)
          } catch (error) {
            examErr = {}
          }
        } else {
          examErr = {}
        }

        examQuestionCopy = Object.assign(examQuestionCopy, {
          questionsList: questionsListCopy,
          parts: list
        })
        examErr[exam_id] = examQuestionCopy

        // return
        sessionStorage.setItem('examErr', JSON.stringify(examErr))
        let url = `/exam?exam_id=${exam_id}&pagename=examErr&subject_id=${subject_id}&exam_type=${this.examType}`
        let { paperMajor } = this
        if (paperMajor === 'dryRun') {
          url += '&paperMajor=dryRun'
        }
        if (paperMajor === 'cpa') {
          url = `/exam/cpa_exam.html?exam_id=${exam_id}&pagename=examErr&subject_id=${subject_id}&exam_type=${this.examType}`
        }
        window.open(url, '_blank')
      }
    },
    // 跳转下一章节
    jumpNext() {
      if (this.nextExamLock && +this.examType !== 8) {
        let message = `${
          +this.nextExamInfo.paper_type === 1 ? '下一节' : '下一套'
        }暂未开放！！！`
        this.$message({ type: 'warning', message })
        return
      }

      // 在跳转到下一章节的时候 主动触发做题上报
      const { nextExamInfo } = this
      if (this.getType(nextExamInfo) !== 'object') {
        this.$message.error('内部错误，请联系管理员！')
        return
      }
      let { nextUrl } = nextExamInfo
      if (!nextUrl) {
        this.$message.error('内部错误，请联系管理员！')
        return
      }
      this.goTo(nextUrl)
    },
    sendZlaClick() {
      this.keyClick({
        ...this.zlaBtn
      })
    },
    // 下一节
    goToNext() {
      let btnStr = +this.nextPaperType === 1 ? '下一节' : '下一套'
      this.zlaBtn = {
        key_name: btnStr,
        key_content: btnStr
      }
      let { nextExamInfo } = this
      if (this.isAllOver) {
        return this.$alert('当前章节练习已学完啦!', '温馨提示')
      }
      if (this.getType(nextExamInfo) !== 'object') {
        this.$message.error('内部错误，请联系管理员！')
        return
      }
      let { groupName, examName } = nextExamInfo
      this.$confirm(
        `是否跳转到<br\><div style="text-align: center;color: #3572ff;font-size: 16px;">${
          groupName ? groupName + '&emsp;' : ''
        }${examName}</div>`,
        '温馨提示',
        {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning',
          dangerouslyUseHTMLString: true,
          center: true
        }
      )
        .then(() => {
          this.jumpNext()
        })
        .catch(err => {
          this.$message({
            message: '已取消',
            type: 'info'
          })
        })
      return
    },
    //私教学习中心后端统计接口
    submitQuestionRecord() {
      let { exam_id, subject_id, subject_power_id } = this.query
      let params = {
        exam_id,
        subject_id,
        subject_power_id
      }
      submitQuestionRecord(params).then(() => {})
    },
    // 重新练习，清空做题数据及状态
    redo() {
      let { paperMajor, examInitModel, query } = this
      let { exam_id, id } = query
      let strBtn = +examInitModel === 1 ? '再做一次' : '再考一次'
      this.zlaBtn = {
        key_name: strBtn,
        key_content: strBtn
      }

      // 万人模考,重新回到
      if (paperMajor === 'dryRun') {
        this.$confirm('重新做题，将会清除你的做题记录哦', '确定再考一次', {
          type: 'warning'
        })
          .then(() => {
            resetExam({
              id,
              exam_id,
              position: 1
            })
              .then(() => {
                // 需要跟新本地缓存，实现多标签页通信
                storage.set(`exam_type_${exam_id}`, '1')
                // 删除query中的type
                delete query.type
                delete query.is_paper
                this.goTo('/exam/views/examEntry2.html', {
                  query,
                  watch: true
                })
              })
              .catch(err => {
                this.$message.error(err.msg || '网络错误，请稍后重试！')
              })
          })
          .catch(err => {})

        return
      }

      // 统一题库
      this.$emit('clearAnswerData', {
        title: examInitModel === 2 ? '确定再考一次' : '确定再做一次',
        content: '重新做题，将会清除你的做题记录哦',
        closeReport: true,
        isFromReport: true
      })
    },
    // 计算最终渲染数据
    computedReportList() {
      let { partAnswerScore } = this
      let { questionsList } = this.examQuestion
      let { parts } = this.examQuestion
      this.reportList = []
      // 大的分类
      if (this.isArray(parts)) {
        parts.forEach(item => {
          let { title } = item
          let obj = {
            title
          }
          let index = this.reportList.findIndex(
            itey => itey.reportname === title
          )
          if (index < 0) {
            this.reportList.push(obj)
          }
        })
      }

      if (this.reportList.length !== Object.keys(partAnswerScore).length) {
        this.$message.error('数据长度不一致，请刷新重试')
        return
      }

      let index = 0
      for (const key in partAnswerScore) {
        let { score, partScore, type } = partAnswerScore[key]
        let { title } = this.reportList[index]
        let obj = {
          type,
          description:
            parts[index] && parts[index].description
              ? parts[index].description
              : '', // 分类描述
          title: this.delTitleIndex(title), // 试题分类名称
          totalCount: 0, // 已做的题数
          score, // 得分
          accuracy: '0%',
          children_n: 0, // 没做数量
          children_r: 0, // 做对数量
          children_w: 0, // 做错数量
          children_d: 0, // 已做数量
          children_score: 0, // 每题分数
          // 当前分类题详细数据
          children: [],
          partScore // 当前分类总分
        }

        this.reportList[index] = obj
        index++
      }

      // 处理每个分类下的题型统计
      if (!this.isArray(questionsList)) return
      questionsList.forEach((item, questIndex) => {
        let { status, partIndex, score, type, options } = item
        let partIndexC = Number(partIndex.replace('part_', ''))
        if (+type === 3) {
          let { paperMajor } = this
          // 组合题
          if (
            ['normal', 'dryRun'].includes(paperMajor) &&
            this.isArray(options)
          ) {
            options.forEach((itey, indey) => {
              switch (itey.status) {
                case 'n':
                  this.reportList[partIndexC].children_n++
                  this.reportList[partIndexC].children.push({
                    status: 'n'
                  })
                  break
                case 'r':
                  this.reportList[partIndexC].children_r++
                  this.reportList[partIndexC].children.push({
                    status: 'r'
                  })
                  break
                case 'd':
                  this.reportList[partIndexC].children_d++
                  this.reportList[partIndexC].children.push({
                    status: 'd'
                  })
                  break
                case 'w':
                case 'h':
                  this.reportList[partIndexC].children_w++
                  this.reportList[partIndexC].children.push({
                    status: 'w'
                  })
                  break
              }
            })
          }

          if (['cpa'].includes(paperMajor)) {
            if (status === 'd') {
              this.reportList[partIndexC].children_d++
            }
            this.reportList[partIndexC].children.push({
              status,
              index: questIndex + 1
            })
          }
          return
        }
        this.reportList[partIndexC].totalCount++
        if (!this.reportList[partIndexC].children_score) {
          this.reportList[partIndexC].children_score = score
        }
        let str = 'children_'
        str = ['h', 'w'].includes(status) ? str + 'w' : str + status
        this.reportList[partIndexC][str]++
        this.reportList[partIndexC].children.push({
          status,
          index: questIndex + 1
        })
      })

      index = 0
      for (const key in partAnswerScore) {
        if (!this.reportList[index]) return
        let { children_r, children_w } = this.reportList[index]
        const totalCount = children_r + children_w
        Object.assign(this.reportList[index], {
          totalCount,
          accuracy: totalCount
            ? Math.floor((children_r * 100) / totalCount) + '%'
            : '0%'
        })
        index++
      }
    },

    // 计算组合题的每道题的分数
    getCurrentScore(currQ, index, partScore) {
      let { paperMajor } = this
      const { options, userAnswer } = currQ
      if (!this.isArray(options) || !options[index]) {
        return 0
      }
      const row = options[index]
      if (this.getType(row) === 'object') {
        let { status, type, perScore, wrongScore } = row
        // 单选，及判断题
        if (+type === 1 && status === 'r') {
          return Number(partScore)
        }

        if (+type === 2) {
          if (status === 'r') {
            return Number(partScore)
          }

          if (status === 'h') {
            // 不定项需要比对condition的配置
            if (perScore) {
              return Number(
                userAnswer[index].reduce(prev => prev + perScore, 0)
              )
            } else if (paperMajor === 'dryRun') {
              // 万人模考半对需要得一半的分
              return partScore / 2
            }
          }

          if (status === 'w') {
            // 变成负数
            return -Number(wrongScore)
          }
        }
      }
      return 0
    },

    //计算考试得分
    computedScore() {
      let { paperMajor, paperType } = this
      Object.values(this.partAnswerScore).forEach(part => {
        //直接清空，尽量不要更新界面，在后面的循环中更新
        part.rightCount = 0
        part.wrongCount = 0
      })
      let count = 0
      //开始算分
      let { questionsList = [] } = this.examQuestion

      // 处理试卷的题的status
      let list = questionsList.map((item, index) => {
        let { type, answer, userAnswer, select_count, status, options } = item

        switch (+type) {
          case 1:
          case 2:
            // 处理选择题，判断题
            status = this.computedStatus(
              this.fixedAnswer(answer),
              this.fixedAnswer(userAnswer),
              +type === 2,
              select_count
            )
            break
          case 3:
            // 组合题判断
            if (!this.isArray(options)) break
            item.options = options.map((itey, indey) => {
              if (!this.isArray(userAnswer) || !this.isArray(answer)) {
                return itey
              }
              let userAnswerCurr = this.fixedAnswer(userAnswer[indey])
              let answerCur = this.fixedAnswer(answer[indey])
              if (+itey.type === 4) {
                // 问答题情况
                if (+this.examInitModel === 1 && +itey.questionModel === 1) {
                  itey.status = 'n'
                } else {
                  itey.status =
                    this.isArray(userAnswerCurr) &&
                    userAnswerCurr.length === 1 &&
                    this.isExist(userAnswerCurr[0])
                      ? 'd'
                      : 'n'
                }
              }

              if ([1, 2].includes(+itey.type)) {
                // 选择题与判断题
                itey.status = this.computedStatus(
                  answerCur,
                  userAnswerCurr,
                  +itey.type === 2,
                  select_count
                )
              }
              return itey
            })

            // 由于注会的组合题是只当一道题处理，故需要单独处理
            if (['cpa'].includes(paperMajor)) {
              status = item.options.some(itey => itey.status !== 'n')
                ? 'd'
                : 'n'
            }
            break
          case 4:
            // 问答题
            if (
              +this.examInitModel === 1 &&
              +item.questionModel === 1 &&
              this.paperMajor !== 'cpa'
            ) {
              status = 'n'
            } else {
              let qType = this.getType(userAnswer)
              if (
                qType === 'array' &&
                userAnswer.length > 0 &&
                this.isExist(userAnswer[0])
              ) {
                status = 'd'
              } else if (qType === 'string' && userAnswer) {
                status = 'd'
              } else {
                status = 'n'
              }
            }

            break
        }

        item.status = status
        return item
      })
      // 万人模考的特殊处理
      if (paperMajor === 'dryRun' && +paperType !== 2) return
      // 处理判分
      list.forEach(item => {
        let {
          score,
          perScore,
          type,
          userAnswer,
          partIndex,
          status,
          options
        } = item

        // 问答题4及注会下的组合题3不参与计算分数
        if (+type === 4 || (paperMajor === 'cpa' && +type === 3)) return
        let part = this.partAnswerScore[partIndex]

        switch (+type) {
          // 选择题，判断题
          case 1:
          case 2:
            //全对得全分
            if (status === 'r') {
              count += score
              part.score += score
            }

            //如果有perScore，半对得对应分
            if (status === 'h') {
              if (perScore) {
                let half = userAnswer.reduce(prev => prev + perScore, 0)
                count += half
                part.score += half
              } else if (paperMajor === 'dryRun') {
                // 万人模考半对需要得一半的分
                count += score / 2
                part.score += score / 2
              }
            }
            break
          case 3:
            // 组合题
            if (this.isArray(options) && options.length > 0) {
              options = options.map((itey, indey) => {
                let currentScore = this.getCurrentScore(item, indey, item.score)
                if (currentScore) {
                  itey.currentScore = currentScore
                  part.score += currentScore
                }
                return itey
              })
            }
            break
        }

        this.$set(this.partAnswerScore, partIndex, part)
      })

      // 不定项选择总得分不能低于0分
      let judges = list.filter(item => item.type === 2)
      if (judges.length) {
        //正确/错误得分
        let judgeCountRight = 0
        let judgeCountWrong = 0
        // 1、有多个分类下都有不定项选择题怎么办?
        let partIndex = ''

        judges.forEach(item => {
          let { score, wrongScore, status } = item
          partIndex = item.partIndex
          // 2、为何没处理h的情况？
          //正确打分
          if (status === 'r') judgeCountRight += score
          //错误打分
          if (status === 'w') {
            if (wrongScore) judgeCountWrong += wrongScore
          }
        })

        let judgeCutScore = judgeCountRight - judgeCountWrong
        let score = judgeCutScore >= 0 ? judgeCutScore : 0
        if (judgeCountWrong > 0) {
          // 存在扣分的情况
          let part = this.partAnswerScore[partIndex]
          this.$set(
            this.partAnswerScore,
            partIndex,
            Object.assign(part, {
              wrongScore: judgeCountWrong,
              score
            })
          )
        }
      }
    },

    createPartScore() {
      // 生成每部分的得分情况
      if (!this.isArray(this.examQuestion.questionsList)) return
      this.examQuestion.questionsList.forEach(item => {
        let { partIndex, partScore, type } = item
        //处理每一部分的得分情况
        if (!this.partAnswerScore[partIndex])
          this.$set(this.partAnswerScore, partIndex, {
            type,
            partScore, //该部分总分
            score: 0, //得分
            wrongScore: 0, //扣分
            wrongCount: 0, //答错
            rightCount: 0, //答对
            halfCount: 0 //半对
          })
      })
    },
    // 获取题的样式类名
    getStatusClassCpa({ status }) {
      let obj = {
        n: 'c-default',
        r: 'c-success b-c-success',
        w: 'c-danger b-c-danger',
        h: 'c-danger b-c-danger',
        d: 'c-primary b-c-primary'
      }
      return obj[status] || ''
    },

    // 获取题的样式类名
    getStatusClass(id, index) {
      let quest = this.examQuestion.questionsList.find(
        item => item.question_id === id
      )

      let obj = {
        n: 'c-default',
        r: 'c-success b-c-success',
        w: 'c-danger b-c-danger',
        h: 'c-danger b-c-danger',
        d: 'c-primary b-c-primary'
      }
      if (index === undefined && quest && quest.status) {
        return obj[quest.status]
      }
      if (!quest || !this.isArray(quest.options) || !quest.options[index]) {
        return ''
      }

      let { status } = quest.options[index]

      if (!status) {
        return ''
      }

      return obj[status] || ''
    }
  }
}
</script>

<style scoped name="csslint-ignore">
.bg-f5 {
  background: #f5f5f5;
  max-width: 100vw;
  overflow-x: hidden;
}
.report {
  padding: 74px 0 70px;
  height: 100vh;
  overflow-y: hidden;
  width: 100vw;
  background: linear-gradient(
    180deg,
    rgba(52, 128, 255, 0.77) 0%,
    rgba(245, 245, 245, 0) 300px
  );
}
header {
  position: absolute;
  top: 0;
  left: 0;
  width: 100vw;
  height: 74px;
  background: #ffffff;
}
.report-header-center {
  width: 1200px;
  height: 74px;
  margin: 0 auto;
}
.eport-fixed-bottom {
  position: absolute;
  bottom: 0;
  left: 0;
  background: #ffffff;
}
.report-fixed-center-content {
  width: 1200px;
  height: 70px;
}
.report-btn-default {
  width: 132px;
  height: 40px;
  border-radius: 4px;
  border: 1px solid #3480ff;
  font-size: 16px;
  font-weight: 400;
  color: #3480ff;
}
.report-btn-warning {
  margin-left: 20px;
  width: 132px;
  height: 40px;
  background: #ff7038;
  border-radius: 4px;
  font-size: 16px;
  font-weight: 400;
  color: #ffffff;
}
.m-l-20 {
  margin-left: 20px;
}
.report-content {
  box-sizing: border-box;
  height: calc(100vh - 144px);
  overflow-y: auto;
  margin: 0;
}
.report-container {
  padding: 20px 0;
  width: 1200px;
  margin: 0 auto;
}
.report-base {
  width: 1200px;
  background: #ffffff;
  border-radius: 12px;
  padding: 30px;
}
.report-left-info {
  padding: 16px;
  width: 400px;
  /* height: 228px; */
  border-radius: 8px;
  border: 1px solid #f2f2f2;
}
.fen-label {
  height: 22px;
  font-size: 16px;
  font-weight: 400;
  color: #383838;
  line-height: 22px;
}
.fen-num {
  height: 22px;
  font-size: 16px;
  font-weight: 400;
  color: #ff5338;
  line-height: 22px;
}
.juan-time {
  color: #3480ff;
}
.report-title {
  height: 28px;
  font-size: 20px;
  font-weight: 600;
  color: #383838;
  line-height: 28px;
}
.m-t-30 {
  margin-top: 30px;
}

.report-fixed /deep/ .el-table thead th {
  background-color: #f7f7f7;
  font-size: 16px;
  font-weight: 400;
  color: #999999;
  height: 57px;
}
.report-fixed /deep/ .el-table tbody td {
  height: 56px;
}
.report-tip {
  text-align: center;
  height: 20px;
  font-size: 14px;
  font-weight: 400;
  color: #999999;
  line-height: 20px;
}
.report-lists {
  margin: 0 auto;
  margin-top: 20px;
  width: 1200px;
  background: #ffffff;
  border-radius: 12px;
  padding: 30px;
}
.report-item-title {
  height: 25px;
  font-size: 18px;
  font-weight: 500;
  color: #383838;
  line-height: 25px;
}
.report-numbs-right {
  height: 17px;
  font-size: 12px;
  font-weight: 400;
  color: #8c8c8c;
  line-height: 17px;
}
.report-numbs-right-item {
  margin-right: 12px;
  width: 63px;
  height: 17px;
  font-size: 12px;
  font-weight: 400;
  color: #8c8c8c;
  line-height: 17px;
}
.report-numbs-right-item-total {
  height: 17px;
  font-size: 12px;
  font-weight: 500;
  color: #bfbfbf;
  line-height: 17px;
}
.report-tips {
  margin-top: 10px;
  font-size: 14px;
  font-weight: 400;
  color: #8c8c8c;
  line-height: 20px;
}

.report-list-item-list {
  flex-wrap: wrap;
}
.report-list-item-list-item {
  margin-top: 16px;
  margin-right: 20px;
  width: 30px;
  height: 30px;
  border-radius: 4px;
  border: 1px solid #999999;
  font-size: 14px;
  font-weight: 400;
  color: #999999;
}

.f-16 {
  font-size: 16px;
}
.c-success {
  color: #00b085;
}

.b-c-success {
  /* css-ignore */
  border-color: #00b085;
}
.c-danger {
  /* css-ignore */
  color: #ff5338;
}
.b-c-danger {
  /* css-ignore */
  border-color: #ff5338;
}
.c-primary {
  /* css-ignore */
  color: #3480ff;
}
.b-c-primary {
  /* css-ignore */
  border-color: #3480ff;
}

.report-fixed-bottom {
  background-color: #fff;
}
.cu {
  cursor: pointer;
}
.logo {
  height: 34px;
}
.dor {
  border-radius: 50%;
  width: 3px;
  height: 3px;
  background: #3480ff;
  margin: 0 10px;
}
/* .page-title-img {
  height: 34px;
} */
/* .user-header-img {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  object-fit: contain;
} */
.goback {
  margin-left: 2px;
  height: 20px;
  font-size: 14px;
  font-weight: 500;
  color: #383838;
  line-height: 20px;
}
.goback:hover {
  color: #383838;
}
.report-fixed /deep/ .el-table {
  border-radius: 4px;
  border: 1px solid #f2f2f2;
  border-bottom: none;
}
.report-fixed /deep/ .el-table table td {
  border: none;
  border-top: 1px solid #f0f0f0;
}
.report-fixed /deep/ .el-table table th {
  border: none;
}
.report-fixed /deep/ .el-table td,
.el-table th {
  padding: 17px 0;
}
.report-chart {
  margin-top: 20px;
}
.report-fixed {
  position: fixed;
  left: 0;
  top: 0;
  z-index: 999;
  width: 100vw;
  height: 100vh;
}
.w-1140 {
  width: 1140px;
}
.zuhe-title {
  margin-top: 16px;
  height: 20px;
  font-size: 14px;

  font-weight: 400;
  color: #383838;
  line-height: 20px;
}
.c-38 {
  color: #383838;
}

.p-r-8 {
  padding-right: 8px;
}
.p-time {
  text-align: center;

  height: 22px;
  font-size: 16px;
  font-weight: 400;
  color: #383838;
  line-height: 22px;
}
.p-t-number {
  margin-top: 12px !important;
}
</style>
